/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.fedex;

import com.fedex.track.stub.*;

import java.text.SimpleDateFormat;
//
/** 
 * Sample code to call the FedEx Notification Web Service
 * <p>
 * com.fedex.track.stub is generated via WSDL2Java, like this:<br>
 * <pre>
 * java org.apache.axis.wsdl.WSDL2Java -w -p com.fedex.track.stub http://www.fedex.com/...../TrackService?wsdl
 * </pre>
 * 
 * This sample code has been tested with JDK 5 and Apache Axis 1.4
 */
public class TrackNotificationWebServiceClient {
//
	public static void main(String[] args) throws Exception {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
	    //
		SendNotificationsRequest request = new SendNotificationsRequest();

        request.setClientDetail(createClientDetail());
        request.setWebAuthenticationDetail(createWebAuthenticationDetail());
        //
        VersionId versionId = new VersionId("trck", 9, 0, 0);
        request.setVersion(versionId);
	    //
	    TransactionDetail transactionDetail = new TransactionDetail();
	    transactionDetail.setCustomerTransactionId("java sample - TrackNotificationRequest"); //This is decode reference field for the customer.  Any value can be used and will be provided in the return.
	    request.setTransactionDetail(transactionDetail);
	    //
	    //If the tracking number is not set as decode system property replace getSystemProperty with tracking number.
	    request.setTrackingNumber(/*getSystemProperty("TrackingNumber")*/ "123456789012");
	    //
	    //Use if date range lookup is needed.
	    //request.setShipDateRangeBegin(dateFormat.parse(getSystemProperty("StartDate"))); // Replace with your range begin date
	    //request.setShipDateRangeEnd(dateFormat.parse(getSystemProperty("EndDate"))); // Replace with your range end date
	    //
	    request.setSenderEMailAddress("test@test.test"); //replace with your email address
	    request.setSenderContactName("Tester");
	    EMailNotificationDetail nd = new EMailNotificationDetail();
	    EMailNotificationRecipient nr = new EMailNotificationRecipient();
	    nr.setEMailAddress("test1@test.test"); //replace with your email address
	    nr.setEMailNotificationRecipientType(EMailNotificationRecipientType.RECIPIENT);
	    nr.setFormat(EMailNotificationFormatType.HTML);
	    EMailNotificationEventType notificationEventTypes[]=new EMailNotificationEventType[3];
	    	notificationEventTypes[0]= EMailNotificationEventType.ON_DELIVERY;
	    	notificationEventTypes[1]= EMailNotificationEventType.ON_SHIPMENT;
	    	notificationEventTypes[2]= EMailNotificationEventType.ON_EXCEPTION;
	    nr.setNotificationEventsRequested(notificationEventTypes);
	    nd.setRecipients(new EMailNotificationRecipient[] {nr});
	    nd.setPersonalMessage("Test message");
	    request.setNotificationDetail(nd);
	    //
		try {
			// Initialize the service
			TrackServiceLocator service;
			TrackPortType port;
			//
			service = new TrackServiceLocator();
			updateEndPoint(service);
			port = service.getTrackServicePort();	
			// This is the call to the web service
			SendNotificationsReply reply = port.sendNotifications(request);
			//
			if (isResponseOk(reply.getHighestSeverity()))
			{
				System.out.println("--- Package Details ---");
				TrackNotificationPackage[] np = reply.getPackages();
				for(int i = 0; i < np.length; i++)
				{
					System.out.println("Carrier code - " + np[i].getCarrierCode());
					Address destAddress = np[i].getDestination();
					System.out.println("Destination address - ");
					System.out.println("  " + destAddress.getCity()
							+ ", " + destAddress.getStateOrProvinceCode()
							+ " " + destAddress.getCountryCode());
					System.out.println("Tracking number - " + np[i].getTrackingNumber());
				}
			}

			printNotifications(reply.getNotifications());

		} catch (Exception e) {
		    System.out.println(e.getMessage());
		}
	}
	
	private static boolean isResponseOk(NotificationSeverityType notificationSeverityType) {
		if (notificationSeverityType == null) {
			return false;
		}
		if (notificationSeverityType.equals(NotificationSeverityType.WARNING) ||
			notificationSeverityType.equals(NotificationSeverityType.NOTE)    ||
			notificationSeverityType.equals(NotificationSeverityType.SUCCESS)) {
			return true;
		}
 		return false;
	}
    

	private static ClientDetail createClientDetail() {
        ClientDetail clientDetail = new ClientDetail();
        String accountNumber = System.getProperty("accountNumber");
        String meterNumber = System.getProperty("meterNumber");
        
        //
        // See if the accountNumber and meterNumber properties are set,
        // if set use those values, otherwise default them to "XXX"
        //
        if (accountNumber == null) {
        	accountNumber = "510087143"; // Replace "XXX" with clients account number
        }
        if (meterNumber == null) {
        	meterNumber = "118559631"; // Replace "XXX" with clients meter number
        }
        clientDetail.setAccountNumber(accountNumber);
        clientDetail.setMeterNumber(meterNumber);
        return clientDetail;
	}
	
	private static WebAuthenticationDetail createWebAuthenticationDetail() {
        WebAuthenticationCredential wac = new WebAuthenticationCredential();
        String key = System.getProperty("key");
        String password = System.getProperty("password");
        
        //
        // See if the key and password properties are set,
        // if set use those values, otherwise default them to "XXX"
        //
        if (key == null) {
        	key = "HPJKBEnK0WpuyYRy"; // Replace "XXX" with clients key
        }
        if (password == null) {
        	password = "N4q8W2qx4Q8vFRobr7aRzZAOK"; // Replace "XXX" with clients password
        }
        wac.setKey(key);
        wac.setPassword(password);
		return new WebAuthenticationDetail(wac);
	}
	
	private static void printNotifications(Notification[] notifications) {
		System.out.println("Notifications:");
		if (notifications == null || notifications.length == 0) {
			System.out.println("  No notifications returned");
		}
		for (int i=0; i < notifications.length; i++){
			Notification n = notifications[i];
			System.out.print("  Notification no. " + i + ": ");
			if (n == null) {
				System.out.println("null");
				continue;
			} else {
				System.out.println("");
			}
			NotificationSeverityType nst = n.getSeverity();

			System.out.println("    Severity: " + (nst == null ? "null" : nst.getValue()));
			System.out.println("    Code: " + n.getCode());
			System.out.println("    Message: " + n.getMessage());
			System.out.println("    Source: " + n.getSource());
		}
	}
	
	private static void updateEndPoint(TrackServiceLocator serviceLocator) {
		String endPoint = System.getProperty("endPoint");
		if (endPoint != null) {
			serviceLocator.setTrackServicePortEndpointAddress(endPoint);
		}
	}

	private static String getSystemProperty(String property){
		String returnProperty = System.getProperty(property);
		if (returnProperty == null){
			return "XXX";
		}
		return returnProperty;
	}
}
